﻿
using live69;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;

namespace RZGD
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public ProcessSetting processSetting = new ProcessSetting();
       
        private void Form1_Load(object sender, EventArgs e)
        {
            string appName = Process.GetCurrentProcess().MainModule.ModuleName;
            SoftAutoStart.RunMenu runMenu = new SoftAutoStart.RunMenu();
            runMenu.QuickName = appName;
            runMenu.QuickNote = "进程监护程序";
            runMenu.SetMeAutoStart(true);

            try
            {
                tim.Interval = 1000;
                tim.Enabled = true;
                tsbStopTime.Text = "暂停自动守护";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }



        private void  getprolist() {
         
            try
            {
                string filename = System.Environment.CurrentDirectory + "\\monitoringlist.txt";
                if (System.IO.File.Exists(filename)==false ) {
                    System.IO.File.WriteAllText(filename,"");
                }
                string sbody= System.IO.File.ReadAllText(filename);
                if (sbody.Length > 0) {
                    processSetting = (ProcessSetting)JsonHelper.DeserializeJSON(sbody, processSetting.GetType());
                    if (processSetting != null) {
                        for (int i = 0; i < processSetting.Plist.Count; i++) {
                            processSetting.Plist[i].state = "";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
         
        }

        private void toshowLV() {
            LV.Items.Clear();
            for (int i = 0; i < processSetting. Plist.Count; i++)
            {
                ProcessItem proset = processSetting.Plist[i];
                ListViewItem it = new ListViewItem();
                it.Tag = proset.id;
                it.Text = proset.name;
                it.SubItems.Add(proset.path);
                it.SubItems.Add(proset.arguments);

                it.SubItems.Add(proset.state);

                it.SubItems.Add(proset.enable.ToString());

                it.SubItems.Add(proset.no_window.ToString());

                it.SubItems.Add(proset.delay_time.ToString());

                LV.Items.Add(it);
            }
        }
        private void tocheck() {
            for (int i = 0; i < processSetting.Plist.Count; i++)
            {
                ProcessItem it = processSetting.Plist[i];
                if (it.enable) {
                    var process = getProcessForRun(it.path);
                    if (process ==  null)
                    {

                        it.starting = true;
                        it.state = "正在启动";
                        //startProcess(it.path, it.arguments);
                        // 创建参数对象
                        // 创建线程，使用ParameterizedThreadStart委托
                        Thread processThread = new Thread(todoStartProcessThread);
                        processThread.IsBackground = true; // 设置为后台线程
                        processThread.Start(it); // 传递参数

                       
                    }
                    else {
                        it.starting=false;
                        it.state = "已启动";
                    }
                }
                processSetting.Plist[i] = it;
            }
        }

        private Process getProcessForRun(string pro_file_name)
        {
            
            // 获取当前系统上所有进程的列表  
            Process[] processes = Process.GetProcesses();
            // 遍历每个进程  
            foreach (Process process in processes)
            {

                // 获取进程名称  
                string processName = process.ProcessName;
                try
                {
                    // 尝试获取进程的主模块（通常是可执行文件）  
                    ProcessModule mainModule = process.MainModule;
                    if (mainModule != null)
                    {
                        if (mainModule.FileName.Equals(pro_file_name))
                        {
                            SafeSetText("进程名称: " + processName + "，正在运行...");
                            return process;
                        }
                    }
                    else
                    {
                        // 如果主模块为空（可能是因为权限不足或其他原因），则打印一条消息  
                        //SafeSetText("进程名称: " + processName + "，无法获取进程所在目录");
                    }
                }
                catch (Exception ex)
                {
                    // 处理可能出现的异常，例如权限不足等  
                   // SafeSetText("进程名称: " + processName + "，发生异常: " + ex.Message);
                }
            }

            return null;

        }


        private void todoStartProcessThread(object param)
        {
            if (param is ProcessItem parameters)
            {
                parameters.starting = true;
                if (parameters.delay_time > 0)
                {
                    // 调用你的startProcess方法
                    Thread.Sleep(parameters.delay_time*1000);
                    startProcess(parameters.path, parameters.arguments, parameters.no_window);
                }
                else {
                    // 调用你的startProcess方法
                    startProcess(parameters.path, parameters.arguments, parameters.no_window);
                }
            }
            else
            {
                SafeSetText("参数类型错误");
            }
        }

        // 线程入口方法，接收参数
        private void StartProcessThread(object param)
        {
            if (param is ProcessItem parameters)
            {
                if (parameters.starting) { return; }
                // 调用你的startProcess方法
                startProcess(parameters.path, parameters.arguments,parameters.no_window);
               
            }
            else
            {
                SafeSetText("参数类型错误");
            }
        }
        private void startProcess(string FileName,string arguments,bool CreateNoWindow)
        {
            try
            {
                // 验证文件是否存在
                if (!File.Exists(FileName))
                {
                    SafeSetText($"错误: JAR文件不存在 - {FileName}");
                    return;
                }

                ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    FileName = FileName,
                    Arguments = arguments,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = CreateNoWindow,
                };

                // 启动进程
                using (Process process = new Process { StartInfo = startInfo })
                {
                    process.Start();

                    SafeSetText("正在启动"+ FileName + "...");

                    // .NET 4.0中使用Thread代替Task.Run
                    Thread outputThread = new Thread(() => ReadOutput(process.StandardOutput, "输出"));
                    Thread errorThread = new Thread(() => ReadOutput(process.StandardError, "错误"));

                    outputThread.IsBackground = true;
                    errorThread.IsBackground = true;

                    outputThread.Start();
                    errorThread.Start();

                    // 等待进程完成
                    process.WaitForExit();

                    // 等待输出线程处理完毕
                    outputThread.Join(1000);
                    errorThread.Join(1000);

                    SafeSetText($"应用已退出，退出代码: {process.ExitCode}");
                }
            }
            catch (Exception ex)
            {
                SafeSetText($"启动应用时发生错误: {ex.Message}");
                SafeSetText($"错误详情: {ex.StackTrace}");
            }
        }

       


        private void tsbshuaxin_Click(object sender, EventArgs e)
        {
            reload();
        }

        private void reload() {
            try
            {
                getprolist();
                tocheck();
                toshowLV();
            }
            catch (Exception ex)
            {
                SafeSetText(ex.Message);
            }

        }

        private void LV_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (LV.SelectedItems.Count > 0) {
                long id = DTH.getInt64(LV.SelectedItems[0].Tag);
                for (int i = 0; i < processSetting.Plist.Count; i++) {
                    if (id == processSetting.Plist[i].id) { 
                        var item = processSetting.Plist[i];
                     txtPath.Text= item.path;
                     txtPname.Text = item.name;
                        txt_arguments.Text = item.arguments;
                        cb_enabled.Text= item.enable.ToString();
                        cb_no_window.Text= item.no_window.ToString();
                        txtdelay_time.Text= item.delay_time.ToString();
                    }
                }
                btnOK.Text = "修改";
                btnOK.Tag = LV.SelectedItems[0].Tag;
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            try
            {
                if (txtPname.Text == "")
                {
                    MessageBox.Show("进程名称不能为空"); return;
                }
                if (txtPath.Text == "")
                {
                    MessageBox.Show("路径不能为空"); return;
                }


                if (btnOK.Text.Equals("添加"))
                {
                    ProcessItem item = new ProcessItem();
                    item.id = myRandom.getCmdID();
                    item.name = txtPname.Text;
                    item.path = txtPath.Text;
                    item.arguments = txt_arguments.Text;
                    item.no_window = DTH.getBool(cb_no_window.Text);
                    item.enable = DTH.getBool(cb_enabled.Text);
                    item.delay_time = DTH.getInt(txtdelay_time.Text);
                    
                    processSetting.Plist.Add(item);
                }
                else {

                    for (int i = 0; i< processSetting.Plist.Count ; i++) {
                        ProcessItem item = processSetting.Plist[i];
                        if (item.id ==DTH.getInt64(btnOK.Tag)) {
                            item.name = txtPname.Text;
                            item.path = txtPath.Text;
                            item.arguments = txt_arguments.Text;
                            item.no_window = DTH.getBool(cb_no_window.Text);
                            item.enable = DTH.getBool(cb_enabled.Text);
                            item.delay_time = DTH.getInt(txtdelay_time.Text);
                            processSetting.Plist[i] = item;
                        }
                    }
                }

                txtPath.Text = "";
                txtPname.Text = "";
                btnOK.Text = "添加";
                btnOK.Tag = 0;

                toshowLV();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            toshowLV();

        }

        private void tsbSave_Click(object sender, EventArgs e)
        {
            try
            {
                string filename = System.Environment.CurrentDirectory + "\\monitoringlist.txt";
                //System.IO.File.WriteAllText(filename, ""); //清空
                processSetting.save_time = DateTime.Now;
                String json= JsonHelper.SerializeJSON(processSetting);
                System.IO.File.WriteAllText(filename, json); //保存
                MessageBox.Show("保存成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            
        }

        private void tim_Tick(object sender, EventArgs e)
        {
            reload();
            tim.Interval = 1000 * 60;
            tim.Enabled = true;
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            if (LV.SelectedItems.Count > 0)
            {
                int del_index = -1;
                for (int i = 0; i < processSetting.Plist.Count; i++) {
                    var id =DTH.getInt64(LV.SelectedItems[0].Tag);
                    if (id == processSetting.Plist[i].id) {
                        del_index= i; break;
                    }
                }

                if (del_index >= 0) {
                    processSetting.Plist.RemoveAt(del_index);
                }

                toshowLV();
            }
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.notifyIcon1.Visible = true;
            }
        }

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            if (this.Visible)
            {
                this.Hide();
            }
            else
            {
                this.Show();
                this.WindowState = FormWindowState.Normal;
            }
        }

        private void btnView_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            if (openFileDialog.ShowDialog() == DialogResult.OK) {

               txtPath .Text  = openFileDialog.FileName;
                
            }
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            // 获取当前系统上所有进程的列表  
            Process[] processes = Process.GetProcesses();
            // 遍历每个进程  
            foreach (Process process in processes)
            {
                // 获取进程名称  
                string processName = process.ProcessName;
                try
                {
                     // 尝试获取进程的主模块（通常是可执行文件）  
                     ProcessModule mainModule = process.MainModule;
                    if (mainModule != null)
                    {
                        // 获取进程所在的目录（即可执行文件所在的目录）  
                        string processDirectory = Path.GetDirectoryName(mainModule.FileName);
                        SafeSetText("进程名称: " + processName +"，进程所在目录: " + mainModule.FileName);
                    }
                    else
                    {
                        // 如果主模块为空（可能是因为权限不足或其他原因），则打印一条消息  
                        SafeSetText("进程名称: " + processName + "，无法获取进程所在目录");
                    }
                }
                catch (Exception ex)
                {
                    // 处理可能出现的异常，例如权限不足等  
                    SafeSetText("进程名称: " + processName +"，发生异常: " + ex.Message);
                }
            }
        }

       

        // 处理流读取的方法
        private static void ReadOutput(StreamReader reader, string prefix)
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                //// 确保控制台输出的线程安全
                //lock (Console.Out)
                //{
                //    SafeSetText($"{prefix}: {line}");
                //}

                Mylogs.LogsAdd_filename(line,"process_console");
            }
        }


        // 停止进程（先尝试正常关闭，失败则强制关闭）
        public void StopProcess(Process _process)
        {
            if (_process == null || _process.HasExited)
            {
                SafeSetText(_process.ProcessName +"进程未在运行");
                return;
            }

            try
            {
                SafeSetText(_process.ProcessName + $"正在关闭进程 (ID: {_process.Id})...");

                // 1. 尝试正常关闭
                if (_process.CloseMainWindow())
                {
                    // 等待最多5秒
                    if (_process.WaitForExit(5000))
                    {
                        SafeSetText(_process.ProcessName + "进程已正常关闭");
                        
                        return;
                    }
                }

                // 2. 正常关闭失败，强制关闭
                _process.Kill();
                _process.WaitForExit();
                SafeSetText(_process.ProcessName +"进程已强制关闭");
               
            }
            catch (Exception ex)
            {
                SafeSetText(_process.ProcessName + $"关闭进程时出错: {ex.Message}");
                
            }
        }

        private void tsbStart_Click(object sender, EventArgs e)
        {
            if (LV.SelectedItems.Count > 0)
            {
                int index = -1;
                for (int i = 0; i < processSetting.Plist.Count; i++)
                {
                    var id = DTH.getInt64(LV.SelectedItems[0].Tag);
                    if (id == processSetting.Plist[i].id)
                    {
                        index = i; break;
                    }
                }

                if (index >= 0)
                {
                    StartProcessThread(processSetting.Plist[index]);
                }

                toshowLV();
            }
        }

        private void tsbStop_Click(object sender, EventArgs e)
        {
            if (LV.SelectedItems.Count > 0)
            {
                int index = -1;
                for (int i = 0; i < processSetting.Plist.Count; i++)
                {
                    var id = DTH.getInt64(LV.SelectedItems[0].Tag);
                    if (id == processSetting.Plist[i].id)
                    {
                        index = i; break;
                    }
                }

                if (index >= 0)
                {
                    var stop_process = getProcessForRun(processSetting.Plist[index].path);
                    StopProcess(stop_process);
                }

                toshowLV();
            }
        }



        #region "消息输出"


        string MsgBuf = "";
        int MsgBufMaxLength = 1024;


        string MsgBuf_cj = "";
        int MsgBufMaxLength_cj = 1024;


        public void InInfo(string info)
        {
            if (txtmsg == null) { return; }
            try
            {
                if (txtmsg.Text.Length > 40000)
                {
                    txtmsg.Text = txtmsg.Text.Substring(20000);
                }
                string str = DateTime.Now.ToString() + " " + info + Environment.NewLine;
                txtmsg.AppendText(str);
            }
            catch (Exception)
            {

            }

        }

        public void SafeSetText(string info, string sid = "")
        {
            if (info == null) { return; }
            if (info == "") { return; }

            Mylogs.LogsAdd_filename(info, sid);
            if (this.InvokeRequired)
            {
                _SafeSetTextCall call = delegate (string s)
                {
                    InInfo(info);
                };
  
                this.Invoke(call, info);
            }
            else
                InInfo(info);

        }

       
        


        private delegate void _SafeSetTextCall(string info);


        #endregion

        private void tsbStopTime_Click(object sender, EventArgs e)
        {
            if (tsbStopTime.Text.Equals("暂停守护"))
            {
                tim.Enabled = false;
                tsbStopTime.Text = "恢复守护";
            }
            else {
                tim.Enabled = true;
                tsbStopTime.Text = "暂停守护";
            }

        }
    }
}
